﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using GodPl.Exceptions;

namespace GodPl.GameObjects.Creatures
{
    public enum BriyyaActionType { MoveTowards, Sleep, EatFrom, BreedWith, Hit };

    public abstract class BriyyaAction
    {
        
        protected abstract TimeSpan MinDuration
        {
            get;
        }

        protected abstract TimeSpan MaxDuration
        {
            get;
        }

        protected readonly Briyya actor;
        protected readonly GameObject target;

        public Briyya Actor
        {
            get { return actor; }
        }

        public GameObject Target
        {
            get { return target; }
        }

        /// <summary>
        /// Whether or not action has been started
        /// </summary>
        protected bool begun;

        /// <summary>
        /// Whether or not action has completed successfully
        /// </summary>
        protected bool finished;

        protected TimeSpan elapsed;

        public TimeSpan Elapsed
        {
            get { return elapsed; }
        }


        public BriyyaAction(Briyya actor, GameObject target)
        {
            this.actor = actor;
            this.target = target;
        }

        protected void assertTarget()
        {
            if (target == null)
            {
                throw new ArgumentNullException("target", this.GetType().Name + " action requires target.");
            }
        }

        protected void assertDistance()
        {
            if (actor.DistanceTo(target) > Math.Max(actor.Radius, target.Radius))
            {
                throw new DistanceException(this);
            }
        }

        public virtual void Begin()
        {
            begun = true;
        }

        public virtual void Finish()
        {
            finished = true;
        }

        public virtual void Update(GameTime gameTime)
        {
            if (finished)
            {
                return;
            }
            
            if (begun && !finished)
            {
                elapsed += gameTime.ElapsedGameTime;
            }

            if (elapsed > MaxDuration)
            {
                finished = true;
                return;
            }
        }


        /// <summary>
        /// Returns whether or not 
        /// </summary>
        /// <returns></returns>
        public virtual bool Interrupt()
        {
            return (MinDuration > new TimeSpan(0, 0, 0) && elapsed < MinDuration);
        }


        public virtual bool Done
        {
            get { return finished; }
        }

        public bool Running
        {
            get { return (begun && !finished); }
        }

    }
}
